﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Entities</title>
<link type="text/css" rel="stylesheet" href="bootstrap.min.css" />
</head>

<body>

<ul>
	<li><a href="#DocNugetPackage">Nuget package</a></li>
	<li><a href="#DocConfiguration">Configuration</a><ul>
		<li><a href="#DocEntityMapping">Entity mapping</a></li>
	</ul>
	</li>
	<li><a href="#DocRepositoryImpl">Repository implementation</a><ul>
		<li><a href="#DocDefaultImpl">Custom repositories</a></li>
		<li><a href="#DocCustomRepositoryMethods">Custom repositories</a></li>
		<li><a href="#DocAppBaseRepo">Application specific base repository class</a></li>
	</ul>
	</li>
	<li><a href="#DocSeeAlso">See also</a></li>
</ul>

<p>ASP.NET Boilerplate can work with any O/RM framework. It has built-in 
integration with <strong>NHibernate</strong>. This document will explain how to 
use NHibernate with ASP.NET Boilerplate. See also
<a href="http://www.codeproject.com/Articles/768664/Introduction-to-ASP-NET-Boilerplate" target="_blank">
this article</a> for developing a complete application with ASP.NET Boilerplate 
and NHibernate. It's assumed that you're already familar with NHibernate in a 
basic level.</p>
<h3 id="DocNugetPackage">Nuget package</h3>
<p>Nuget package to use NHibernate as O/RM in ASP.NET Boilerplate is
<a href="http://www.nuget.org/packages/Abp.NHibernate" target="_blank">
Abp.NHibernate</a>. You should add it to your application. It's 
better to implement NHibernate in a seperated assembly (dll) in your application 
and depend on that package from this assembly.</p>
<h3 id="DocConfiguration">Configuration</h3>
<p>To start using NHibernate, you should first configure it. You should write 
configuration code in
<a href="/Pages/Documents/Module-System">PreInitialize</a> of your module.</p>
<pre lang="cs">[DependsOn(typeof(AbpNHibernateModule))]
public class SimpleTaskSystemDataModule : AbpModule
{
    public override void PreInitialize()
    {
        var connStr = ConfigurationManager.ConnectionStrings[&quot;Default&quot;].ConnectionString;

        Configuration.Modules.AbpNHibernate().FluentConfiguration
            .Database(MsSqlConfiguration.MsSql2008.ConnectionString(connStr))
            .Mappings(m =&gt; m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly()));
    }

    public override void Initialize()
    {
        IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
    }
}</pre>
<p><strong>AbpNHibernateModule</strong> module provides base functionality and 
adapters to make NHibernate work with ASP.NET Boilerplate.</p>
<h4 id="DocEntityMapping">Entity mapping</h4>
<p>In this sample configuration, we're fluently mapping using all mapping 
classes in current assembly. An example mapping class can be as shown below:</p>
<pre lang="cs">public class TaskMap : EntityMap&lt;Task&gt;
{
    public TaskMap()
        : base(&quot;TeTasks&quot;)
    {
        References(x =&gt; x.AssignedUser).Column(&quot;AssignedUserId&quot;).LazyLoad();

        Map(x =&gt; x.Title).Not.Nullable();
        Map(x =&gt; x.Description).Nullable();
        Map(x =&gt; x.Priority).CustomType&lt;TaskPriority&gt;().Not.Nullable();
        Map(x =&gt; x.Privacy).CustomType&lt;TaskPrivacy&gt;().Not.Nullable();
        Map(x =&gt; x.State).CustomType&lt;TaskState&gt;().Not.Nullable();
    }
}</pre>
<p><strong>EntityMap</strong> is a class of ASP.NET Boilerplate that extends
<strong>ClassMap&lt;T&gt;</strong>, automatically maps <strong>Id</strong> property and gets <strong>table name</strong> in the constructor. So, I'm deriving from it and mapping other properties 
using <a href="http://www.fluentnhibernate.org/" target="_blank">
FluentNHibernate</a>.&nbsp; Surely, you can derive directly from ClassMap. You 
can use full API of FluentNHibernate. You can also use other mapping techniques 
of NHibernate (like mapping XML files).</p>
<h3>Repository implementation</h3>

<p>You can use default implementation for repositories even without creating a 
repository class in your project. Or you can create your repository class 
derived from NhRepositoryBase.</p>
<h4 id="#DocDefaultImpl">Default implementation</h4>
<p>You don't have to create repository classes for entities to just use 
predefined repository methods. Example:</p>
<pre lang="cs">public class PersonAppService : IPersonAppService
{
    private readonly IRepository&lt;Person&gt; _personRepository;

    public PersonAppService(IRepository&lt;Person&gt; personRepository)
    {
        _personRepository = personRepository;
    }

    public void CreatePerson(CreatePersonInput input)
    {        
        person = new Person { Name = input.Name, EmailAddress = input.EmailAddress };
        
        _personRepository.Insert(person);
    }
}</pre>

<p>PersonAppService contructor-injects <strong>IRepository&lt;Person&gt;</strong> and 
uses the <strong>Insert</strong> method. In this way, you can easily inject
<strong>IRepository&lt;TEntity&gt;</strong> (or IRepository&lt;TEntity, TPrimaryKey&gt;) and 
use predefined methods. See <a href="/Pages/Documents/Repositories">repository 
documentation</a> for list of all predefined methods.</p>
<h4>Custom repositories</h4>
<p>If you want to add some custom method, you should first add it to repository 
interface (as a best practice), then implement in the repository class. ASP.NET Boilerplate provides a base class <strong>NhRepositoryBase</strong> 
to implement repositories easily. To implement IRepository interface, you can 
just derive your repository from this class.</p>
<p>Assume that we have a Task entity that can be assigned to a Person (entity) 
and a Task has a State (new, assigned, completed... and so on). We may need to 
write a custom method to get list of Tasks with some conditions and with 
AssisgnedPerson property pre-fetched in a single database query. See the example 
code:</p>
<pre>public interface ITaskRepository : IRepository&lt;Task, long&gt;
{
    List&lt;Task&gt; GetAllWithPeople(int? assignedPersonId, TaskState? state);
}

public class TaskRepository : NhRepositoryBase&lt;Task, long&gt;, ITaskRepository
{
    public TaskRepository(ISessionProvider sessionProvider)
        : base(sessionProvider)
    {
    }

    public List&lt;Task&gt; GetAllWithPeople(int? assignedPersonId, TaskState? state)
    {
        var query = GetAll();

        if (assignedPersonId.HasValue)
        {
            query = query.Where(task =&gt; task.AssignedPerson.Id == assignedPersonId.Value);
        }

        if (state.HasValue)
        {
            query = query.Where(task =&gt; task.State == state);
        }

        return query
            .OrderByDescending(task =&gt; task.CreationTime)
            .Fetch(task =&gt; task.AssignedPerson)
            .ToList();
    }
}</pre>
<p><strong>GetAll()</strong> returns <strong>IQueryable&lt;Task&gt;</strong>, then we can add some
<strong>Where</strong> filters using given parameters. Finally we can call
<strong>ToList()</strong> to get list of 
Tasks.</p>
<p>You can also use <strong>Session </strong>object in repository methods to use 
full API of NHibernate.</p>
<p>A repository should get ISessionProvider in it's constructor. In this way, we 
can easily inject a fake session provider in unit tests. In runtime, ASP.NET 
Boilerplate automatically injects the right session provider.</p>
<h4 id="DocAppBaseRepo">Application specific base repository class</h4>
<p>Although you can derive your repositories from NhRepositoryBase of ASP.NET 
Boilerplate, it's a better practice to create your own base class that <strong>extends</strong> 
NhRepositoryBase. Thus, you can add shared/common methods to your repositories 
easily. Example:</p>
<pre lang="cs">//Base class for all repositories in my application
public abstract class MyRepositoryBase&lt;TEntity, TPrimaryKey&gt; : NhRepositoryBase&lt;TEntity, TPrimaryKey&gt;
    where TEntity : class, IEntity&lt;TPrimaryKey&gt;
{
    protected MyRepositoryBase(ISessionProvider sessionProvider)
        : base(sessionProvider)
    {
    }

    //add common methods for all repositories
}

//A shortcut for entities those have integer Id.
public abstract class MyRepositoryBase&lt;TEntity&gt; : MyRepositoryBase&lt;TEntity, int&gt;
    where TEntity : class, IEntity&lt;int&gt;
{
    protected MyRepositoryBase(ISessionProvider sessionProvider)
        : base(sessionProvider)
    {
    }

    //do not add any method here, add the class above (since this inherits it)
}

public class TaskRepository : MyRepositoryBase&lt;Task&gt;, ITaskRepository
{
    public TaskRepository(ISessionProvider sessionProvider)
        : base(sessionProvider)
    {
    }

    //Specific methods for task repository
}</pre>

<h3 id="DocSeeAlso">See also</h3>
<p>See <a href="/Pages/Documents/Repositories">repository documentation</a> 
for more information on repositories.</p>

</body>

</html>
